#ifndef PLUGINSYSTEM_H
#define PLUGINSYSTEM_H

#include <QObject>
#include <QPluginLoader>
#include <QDir>
#include <QJsonObject>
#include <QJsonDocument>
#include <QLibrary>
#include <QMap>
#include <QStringList>
#include <functional>

// Forward declarations to avoid conflicts
struct ExportConfig;

/**
 * @brief 审计插件接口
 * 定义外部应用程序集成审计系统时需要实现的接口
 */
class IAuditPlugin
{
public:
    virtual ~IAuditPlugin() = default;
    
    // ==================== 插件信息接口 ====================
    
    /**
     * @brief 获取插件名称
     * @return 插件名称
     */
    virtual QString pluginName() const = 0;
    
    /**
     * @brief 获取插件版本
     * @return 插件版本号
     */
    virtual QString pluginVersion() const = 0;
    
    /**
     * @brief 获取插件描述
     * @return 插件功能描述
     */
    virtual QString pluginDescription() const = 0;
    
    /**
     * @brief 获取插件所需权限列表
     * @return 权限名称列表
     */
    virtual QStringList requiredPermissions() const = 0;
    
    // ==================== 插件生命周期接口 ====================
    
    /**
     * @brief 初始化插件
     * @param config 配置参数
     * @return 初始化是否成功
     */
    virtual bool initialize(const QJsonObject &config) = 0;
    
    /**
     * @brief 关闭插件
     */
    virtual void shutdown() = 0;
    
    // ==================== 审计操作接口 ====================
    
    /**
     * @brief 记录审计事件
     * @param userId 用户ID
     * @param action 操作类型
     * @param details 详细信息
     * @param metadata 元数据
     * @return 记录是否成功
     */
    virtual bool logEvent(const QString &userId, const QString &action, 
                         const QString &details, const QJsonObject &metadata = QJsonObject()) = 0;
    
    /**
     * @brief 查询审计事件
     * @param filter 查询过滤条件
     * @return 事件数组
     */
    virtual QJsonArray queryEvents(const QJsonObject &filter) const = 0;
    
    /**
     * @brief 导出审计数据
     * @param exportConfig 导出配置
     * @return 导出是否成功
     */
    virtual bool exportData(const QJsonObject &exportConfig) = 0;
    
    // ==================== 用户管理接口 ====================
    
    /**
     * @brief 用户身份验证
     * @param username 用户名
     * @param password 密码
     * @return 验证是否成功
     */
    virtual bool authenticateUser(const QString &username, const QString &password) = 0;
    
    /**
     * @brief 检查用户权限
     * @param userId 用户ID
     * @param permission 权限名称
     * @return 是否拥有权限
     */
    virtual bool hasPermission(const QString &userId, const QString &permission) const = 0;
};

Q_DECLARE_INTERFACE(IAuditPlugin, "com.pharmasoft.AuditPlugin/1.0")

/**
 * @brief 插件元数据结构体
 * 存储插件的基本信息和状态
 */
struct PluginInfo {
    QString name;                   // 插件名称
    QString version;                // 插件版本
    QString description;            // 插件描述
    QString filePath;               // 插件文件路径
    QStringList dependencies;       // 依赖项列表
    QStringList permissions;        // 所需权限列表
    bool enabled;                   // 是否启用
    bool loaded;                    // 是否已加载
    QJsonObject config;             // 配置信息
};

// Plugin system manager
class PluginSystem : public QObject
{
    Q_OBJECT

public:
    explicit PluginSystem(QObject *parent = nullptr);
    ~PluginSystem();
    
    // Plugin management
    bool loadPlugin(const QString &pluginPath);
    bool unloadPlugin(const QString &pluginName);
    bool enablePlugin(const QString &pluginName);
    bool disablePlugin(const QString &pluginName);
    
    // Plugin discovery
    QStringList scanForPlugins(const QString &directory);
    QList<PluginInfo> getAvailablePlugins() const;
    QList<PluginInfo> getLoadedPlugins() const;
    
    // Plugin interaction
    IAuditPlugin* getPlugin(const QString &pluginName) const;
    bool callPluginMethod(const QString &pluginName, const QString &method, 
                         const QJsonObject &params, QJsonObject &result);
    
    // Configuration
    bool setPluginConfig(const QString &pluginName, const QJsonObject &config);
    QJsonObject getPluginConfig(const QString &pluginName) const;
    
    // External API for host applications
    bool registerAsExternalPlugin(const QString &hostAppId);
    bool unregisterFromExternalApp(const QString &hostAppId);
    
    // Communication with host applications
    void sendEventToHost(const QString &hostAppId, const QString &event, const QJsonObject &data);
    void registerEventHandler(const QString &event, std::function<void(const QJsonObject&)> handler);
    
    // Plugin security
    bool validatePluginSignature(const QString &pluginPath);
    bool checkPluginPermissions(const QString &pluginName, const QStringList &requiredPermissions);
    
    // Plugin sandboxing
    void setSandboxMode(bool enabled);
    bool isSandboxed() const;
    
    // Plugin communication
    bool sendMessageToPlugin(const QString &pluginName, const QString &message, const QJsonObject &data);
    void broadcastMessage(const QString &message, const QJsonObject &data);

signals:
    void pluginLoaded(const QString &pluginName);
    void pluginUnloaded(const QString &pluginName);
    void pluginError(const QString &pluginName, const QString &error);
    void messageReceived(const QString &fromPlugin, const QString &message, const QJsonObject &data);
    void hostEventReceived(const QString &hostAppId, const QString &event, const QJsonObject &data);

public slots:
    void refreshPlugins();
    void reloadPlugin(const QString &pluginName);

private slots:
    void onPluginDestroyed(QObject *plugin);

private:
    QMap<QString, PluginInfo> m_availablePlugins;
    QMap<QString, QPluginLoader*> m_loadedPlugins;
    QMap<QString, IAuditPlugin*> m_pluginInstances;
    QMap<QString, QObject*> m_pluginObjects; // Store QObject pointers separately
    
    // External application integration
    QMap<QString, QJsonObject> m_hostApplications;
    QMap<QString, std::function<void(const QJsonObject&)>> m_eventHandlers;
    
    // Security and sandboxing
    bool m_sandboxEnabled;
    QStringList m_trustedPluginPaths;
    
    // Plugin directories
    QStringList m_pluginDirectories;
    
    // Helper methods
    bool validatePluginMetadata(const QJsonObject &metadata);
    PluginInfo parsePluginMetadata(const QString &pluginPath);
    bool checkDependencies(const PluginInfo &pluginInfo);
    void setupPluginSandbox(const QString &pluginName);
    void cleanupPlugin(const QString &pluginName);
    
    // Configuration management
    void savePluginConfigs();
    void loadPluginConfigs();
    QString getConfigPath() const;
    
    // Inter-process communication for external plugins
    void setupIPC();
    void handleIPCMessage(const QJsonObject &message);
};

// Convenience macros for plugin development
#define AUDIT_PLUGIN_EXPORT(ClassName) \
    Q_PLUGIN_METADATA(IID "com.pharmasoft.AuditPlugin/1.0") \
    Q_INTERFACES(IAuditPlugin)

// External API wrapper for C-style integration
extern "C" {
    // C API for external applications
    typedef struct {
        const char* name;
        const char* version;
        const char* description;
    } AuditPluginInfo;
    
    typedef struct {
        const char* user_id;
        const char* action;
        const char* details;
        const char* metadata_json;
    } AuditEvent;
    
    typedef struct {
        const char* format;
        const char* output_path;
        const char* filter_json;
    } CExportConfig;
    
    // Plugin lifecycle
    bool audit_plugin_initialize(const char* config_json);
    void audit_plugin_shutdown();
    
    // Audit operations
    bool audit_log_event(const AuditEvent* event);
    char* audit_query_events(const char* filter_json);
    bool audit_export_data(const CExportConfig* config);
    
    // User management
    bool audit_authenticate_user(const char* username, const char* password);
    bool audit_has_permission(const char* user_id, const char* permission);
    
    // Memory management
    void audit_free_string(char* str);
    
    // Plugin information
    AuditPluginInfo audit_get_plugin_info();
}

#endif // PLUGINSYSTEM_H